package com.android.launcher3.util;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class IntMap<T> extends HashMap<Integer, T> {

    private int minKey = Integer.MAX_VALUE;
    private int maxKey = Integer.MIN_VALUE;

    public IntMap() {
        resetKeyScope();
    }

    @Nullable
    @Override
    public T put(Integer key, T value) {
        compKey(key);
        return super.put(key, value);
    }

    @Nullable
    @Override
    public T putIfAbsent(Integer key, T value) {
        compKey(key);
        return super.putIfAbsent(key, value);
    }

    @Override
    public boolean remove(@Nullable Object key, @Nullable Object value) {
        boolean remove = super.remove(key, value);
        if (remove) {
            compKey();
        }
        return remove;
    }

    @Nullable
    @Override
    public T remove(@Nullable Object key) {
        T remove = super.remove(key);
        if (remove != null) {
            compKey();
        }
        return remove;
    }

    @Override
    public void putAll(@NonNull Map<? extends Integer, ? extends T> m) {
        super.putAll(m);
        compKey();
    }

    @Override
    public void clear() {
        super.clear();
        compKey();
    }

    private void resetKeyScope() {
        minKey = Integer.MAX_VALUE;
        maxKey = Integer.MIN_VALUE;
    }

    private void compKey(Integer key) {
        if (key != null) {
            if (key < minKey) {
                minKey = key;
            }
            if (key > maxKey) {
                maxKey = key;
            }
        }
    }

    private void compKey() {
        resetKeyScope();
        Set<Integer> integers = keySet();
        Iterator<Integer> iterator = integers.iterator();
        if (iterator.hasNext()) {
            Integer next = iterator.next();
            compKey(next);
        }
    }

    public Integer getMinKey() {
        if (minKey == Integer.MAX_VALUE) {
            return null;
        }
        return minKey;
    }

    public Integer getMaxKey() {
        if (maxKey == Integer.MIN_VALUE) {
            return null;
        }
        return maxKey;
    }
}
